home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 January: Mac OS SDK / Dev.CD Jan 97 SDK2.toast / Development Kits (Disc 2) / OpenDoc Development Framework / ODFDev / Form / Sources / View.cpp < prev    next >
Encoding:
Text File  |  1996-09-17  |  30.4 KB  |  887 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                View.cpp
  4. //    Release Version:    $ ODF 2 $
  5. //
  6. //    Copyright:            (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  7. //
  8. //========================================================================================
  9.  
  10. #include "Form.hpp"
  11.  
  12. #ifndef VIEW_H
  13. #include "View.h"
  14. #endif
  15.  
  16. #ifndef PART_H
  17. #include "Part.h"
  18. #endif
  19.  
  20. #ifndef FRAME_H
  21. #include "Frame.h"
  22. #endif
  23.  
  24. #ifndef SCROLLED_H
  25. #include "ScrollEd.h"
  26. #endif
  27.  
  28. // ----- Framework Layer -----
  29.  
  30. #ifndef FWUTIL_H
  31. #include "FWUtil.h"
  32. #endif
  33.  
  34. #ifndef FWFRAME_H
  35. #include "FWFrame.h"
  36. #endif
  37.  
  38. #ifndef FWLISTBX_H
  39. #include "FWListBx.h"
  40. #endif
  41.  
  42. #ifndef FWBUTTON_H
  43. #include "FWButton.h"
  44. #endif
  45.  
  46. #ifndef FWEDVIEW_H
  47. #include "FWEdView.h"
  48. #endif
  49.  
  50. #ifndef FWPOPUP_H
  51. #include "FWPopup.h"
  52. #endif
  53.  
  54. #ifndef FWCLUSTR_H
  55. #include "FWClustr.h"
  56. #endif
  57.  
  58. #ifndef FWCONTXT_H
  59. #include "FWContxt.h"
  60. #endif
  61.  
  62. #ifndef FWSCLBAR_H
  63. #include "FWSclBar.h"
  64. #endif
  65.  
  66. #ifndef FWSTATIC_H
  67. #include "FWStatic.h"
  68. #endif
  69.  
  70. // ----- OS Layer -----
  71.  
  72. #ifndef FWMENU_H
  73. #include "FWMenu.h"
  74. #endif
  75.  
  76. #ifndef FWEVENT_H
  77. #include "FWEvent.h"
  78. #endif
  79.  
  80. #ifndef FWRECT_H
  81. #include "FWRect.h"
  82. #endif
  83.  
  84. #ifndef FWRECSHP_H
  85. #include "FWRecShp.h"
  86. #endif
  87.  
  88. #ifndef FWTXTSHP_H
  89. #include "FWTxtShp.h"
  90. #endif
  91.  
  92. #ifndef FWPICSHP_H
  93. #include "FWPicShp.h"        
  94. #endif
  95.  
  96. #ifndef FWALERT_H
  97. #include "FWAlert.h"            
  98. #endif
  99.  
  100. #ifndef FWRESOUR_H
  101. #include "FWResour.h"            
  102. #endif
  103.  
  104. // ----- OpenDoc Includes -----
  105.  
  106. #ifndef SOM_Module_OpenDoc_Commands_defined
  107. #include <CmdDefs.xh>
  108. #endif
  109.  
  110. #ifndef SOM_Module_OpenDoc_StdProps_defined
  111. #include <StdProps.xh>
  112. #endif
  113.  
  114. #ifndef SOM_ODSession_xh
  115. #include <ODSessn.xh>
  116. #endif
  117.  
  118. #ifndef SOM_ODDispatcher_xh
  119. #include <Disptch.xh>
  120. #endif
  121.  
  122. //========================================================================================
  123. // RunTime Info
  124. //========================================================================================
  125.  
  126. #ifdef FW_BUILD_MAC
  127. #pragma segment odfform
  128. #endif
  129.  
  130. FW_DEFINE_CLASS_M1(CFormView, FW_CPictSView)
  131. FW_DEFINE_AUTO(CFormView)
  132.  
  133. #if FW_ODFRC_VIEWS
  134. const FW_ClassTypeConstant LFormView = FW_TYPE_CONSTANT('F','r','m','v');
  135. FW_REGISTER_ARCHIVABLE_CLASS(LFormView, CFormView, CFormView::Create, FW_CView::Read, CFormView::Destroy, FW_CView::Write)
  136. #endif
  137.  
  138. //========================================================================================
  139. // CFormView
  140. //========================================================================================
  141.  
  142. //----------------------------------------------------------------------------------------
  143. // CFormView::CFormView
  144. //----------------------------------------------------------------------------------------
  145.  
  146. CFormView::CFormView(Environment* ev, 
  147.                         FW_CSuperView* container,
  148.                         const FW_CRect& bounds,
  149.                         FW_ResourceID pictID1,
  150.                         FW_ResourceID pictID2) :
  151.     FW_CPictSView(ev, container, bounds, kFormViewID, pictID1, FW_kZeroPoint, FW_kXYScrolling),
  152.     fFirstFormOn(true)
  153. {    
  154.     // Adjust the bounds but don't redraw now 
  155.     CenterInFrame(ev, bounds.Size(), FW_kDontRedraw);
  156.     
  157.     InitializePict(ev, pictID2);
  158. }
  159.  
  160. //----------------------------------------------------------------------------------------
  161. // CFormView::CFormView
  162. //----------------------------------------------------------------------------------------
  163.  
  164. CFormView::CFormView(Environment* ev) :
  165.     FW_CPictSView(ev),
  166.     fFirstFormOn(true)
  167. {    
  168.     // Adjust the bounds but don't redraw now 
  169. //     CenterInFrame(ev, contentRect.Size(), FALSE);  can do that here?
  170. }
  171.  
  172. //----------------------------------------------------------------------------------------
  173. // CFormView::~CFormView
  174. //----------------------------------------------------------------------------------------
  175.  
  176. CFormView::~CFormView()
  177. {
  178. }
  179.  
  180. //----------------------------------------------------------------------------------------
  181. // CFormView::InitializePict
  182. //----------------------------------------------------------------------------------------
  183.  
  184. void CFormView::InitializePict(Environment* ev, FW_ResourceID pictID) 
  185. {    
  186.     FW_TRY
  187.     {
  188.         // Load the 2nd picture from the part shared library
  189.         FW_PSharedLibraryResourceFile resFile(ev);
  190.         fPicture2 = FW_CPicture(resFile, pictID);
  191.     }
  192.     FW_CATCH_BEGIN
  193.     FW_CATCH_REFERENCE(FW_XException, except)
  194.     {
  195.         // Picture will be replaced by message "Picture not found!"
  196.         fPicture2 = 0;
  197.     }
  198.     FW_CATCH_END
  199. }
  200.  
  201. //----------------------------------------------------------------------------------------
  202. // CFormView::ActivateTarget
  203. //----------------------------------------------------------------------------------------
  204. // ActivateTarget is called the first time the frame gets the selection focus (because
  205. // a content view is always the frame's default target). We use this to change the target 
  206. // to be the first text-edit field, i.e. to activate this field for keyboard events.
  207.  
  208. void CFormView::ActivateTarget(Environment* ev, FW_Boolean tabSelection)
  209. {
  210.     FW_CView* edview = FindViewByID(ev, kFirstNameEdViewID);
  211.     
  212.     // Be sure that the edit view wants to be the target before doing it
  213.     // (otherwise it would be activated even when it's invisible in the 2nd form)
  214.      
  215.     if (edview->WantsToBeTarget(ev))
  216.         edview->BecomeTarget(ev, tabSelection);
  217. }
  218.  
  219. //----------------------------------------------------------------------------------------
  220. //    CFormView::PostCreateViewFromStream
  221. //----------------------------------------------------------------------------------------
  222. // PostCreateViewFromStream is called after subviews are created from resources.  
  223. // Implement initializations for this view that can't be done from a stream.
  224.  
  225. void CFormView::PostCreateViewFromStream(Environment* ev)
  226. {
  227.     // ----- Link the frame to the list-box in order to respond to double-clicks
  228.     //        (standard controls are linked by defining their "receiver" resource field)
  229.     
  230.     // Note: this code could also reside in CFormFrame::PostCreateViewFromStream
  231.     //         if you prefer to do all PostCreate initializations in one place.
  232.     
  233.     CFormFrame* frame = (CFormFrame*)GetFrame(ev);
  234.     FW_CListBox* listbox = (FW_CListBox*)FindViewByID(ev, kPlatformListBoxID);
  235.     FW_ASSERT(listbox);
  236.     
  237.     frame->AddInterest(listbox, FW_kListBoxDoubleClickedMsg);
  238.     
  239.     // ----- Add a behavior to the list-box to handle mouse clicks
  240.     //        (easier than subclassing FW_CListBox and defining a new resource type)
  241.     
  242.     CMouseUpBehavior* behavior = FW_NEW(CMouseUpBehavior, (ev, listbox));
  243.     listbox->AdoptEventHandler(ev, behavior);
  244.     
  245.     // ----- Disable the "Remove" button by default
  246.     FW_CButton* rmButton = (FW_CButton*) FindViewByID(ev, kRemoveButtonID);
  247.     rmButton->Disable(ev);
  248.     
  249. #if FW_PPOB_VIEWS
  250.     // Constructor doesn't let you initialize the list-box items so we must do it here
  251.     // (we use AddStringItem because the number of items wasn't initialized either)
  252.     listbox->SetDrawingMode(ev, FALSE);
  253.     listbox->AddStringItem(ev, FW_CString("Mac OS"));
  254.     listbox->AddStringItem(ev, FW_CString("OS/2 Warp"));
  255.     listbox->AddStringItem(ev, FW_CString("Windows 95"));
  256.     listbox->AddStringItem(ev, FW_CString("Windows NT"));
  257.     listbox->AddStringItem(ev, FW_CString("IBM AIX"));
  258.     listbox->AddStringItem(ev, FW_CString("Sun Sparc Solaris"));
  259.     listbox->AddStringItem(ev, FW_CString("Sun OS 4.1.x"));
  260.     listbox->AddStringItem(ev, FW_CString("HP /UX"));
  261.     listbox->AddStringItem(ev, FW_CString("Unix IRIX"));
  262.     listbox->AddStringItem(ev, FW_CString("Unix Linux"));
  263.     listbox->SetDrawingMode(ev, TRUE);
  264. #endif
  265. #if FW_MACAPP_VIEWS
  266.     // AdLib doesn't let you initialize the list-box items so we must do it here
  267.     // However the number of items is initialized so we can use SetStringItem
  268.     listbox->SetDrawingMode(ev, FALSE);
  269.     listbox->SetStringItem(ev, 1, FW_CString("Mac OS"));
  270.     listbox->SetStringItem(ev, 2, FW_CString("OS/2 Warp"));
  271.     listbox->SetStringItem(ev, 3, FW_CString("Windows 95"));
  272.     listbox->SetStringItem(ev, 4, FW_CString("Windows NT"));
  273.     listbox->SetStringItem(ev, 5, FW_CString("IBM AIX"));
  274.     listbox->SetStringItem(ev, 6, FW_CString("Sun Sparc Solaris"));
  275.     listbox->SetStringItem(ev, 7, FW_CString("Sun OS 4.1.x"));
  276.     listbox->SetStringItem(ev, 8, FW_CString("HP /UX"));
  277.     listbox->SetStringItem(ev, 9, FW_CString("Unix IRIX"));
  278.     listbox->SetStringItem(ev, 10, FW_CString("Unix Linux"));
  279.     listbox->SetDrawingMode(ev, TRUE);
  280. #endif
  281.  
  282. }
  283.  
  284. //----------------------------------------------------------------------------------------
  285. // CFormView::CreateSubViews
  286. //----------------------------------------------------------------------------------------
  287. // Called from CFormFrame::CreateSubViews if compiled without using view resources
  288.  
  289. void CFormView::CreateSubViews(Environment* ev)
  290. {
  291. FW_UNUSED(ev);
  292. #if !FW_ODFRC_VIEWS && !FW_PPOB_VIEWS && !FW_MACAPP_VIEWS
  293.  
  294.     // This code is compiled only if you didn't define any of the 3 FW_XXX_VIEWS flags
  295.     // NOTE: You'll may get an "Out of memory" error if you don't have a LOT of memory on
  296.     // your Mac. It must be caused by the full-optimization flags used in Release mode.
  297.     FW_Fixed fixed20     = FW_IntToFixed(20);
  298.     FW_Fixed fixed40     = FW_IntToFixed(40);
  299.     FW_CFont timesBold(FW_kTimes, FW_kBold, FW_IntToFixed(12));
  300.     FW_CFont helvetica(FW_kHelvetica, FW_kPlain, FW_IntToFixed(12));
  301.  
  302.     FW_CRect viewRect;        // working rect for creating the views
  303.  
  304.     // ----- Create edit fields in the content view
  305.     viewRect.Set(FW_IntToFixed(290), FW_IntToFixed(90), FW_IntToFixed(450), FW_IntToFixed(107));
  306.     FW_CPoint offset(FW_kFixed0, fixed20);
  307.     for (int i = 0; i < 4; i++) {
  308.         FW_CEditView* editView = FW_NEW(FW_CEditView, (ev, this, kFirstNameEdViewID+i, viewRect));
  309.         editView->SetFont(ev, timesBold);
  310.         viewRect += offset;
  311.     }
  312.     
  313.     // ----- Create custom scrolling edit view with its scrollbar
  314.     viewRect.Set(FW_IntToFixed(30), FW_IntToFixed(200), FW_IntToFixed(450), FW_IntToFixed(290));    
  315.     FW_CRect vertSbRect(viewRect.right - FW_kFixedPos1, viewRect.top, 
  316.                         viewRect.right + FW_IntToFixed(15), viewRect.bottom);
  317.     FW_CScrollBar* vertSB = FW_NEW(FW_CScrollBar, (ev, this, kEditVScrollBarID, vertSbRect));
  318.     vertSB->SetBindings(ev, FW_kFixedBounds);
  319.     CScrollEdit* scrollEdit = FW_NEW(CScrollEdit, (ev, this, kFirstNameEdViewID+4, viewRect, NULL, vertSB, FW_CString()));
  320.  
  321.     // ----- Create the "Subscribe" check box 
  322.     //         Use null message (no receiver) and initial value of 1 to turn it on
  323.     viewRect.Set(FW_IntToFixed(30), FW_IntToFixed(310), FW_IntToFixed(200), FW_IntToFixed(324));
  324.     FW_CButton* check = FW_NEW(FW_CButton, (ev, this, kSubscribeCheckID, viewRect, FW_kCheckButton, 
  325.                                 FW_CString("Subscribe to ODFFlash"), timesBold, 0, 1));
  326.  
  327.     // ----- Create the Modem Speed radio butttons, their group box & the radio cluster
  328.     viewRect.Set(FW_IntToFixed(30), FW_IntToFixed(360), FW_IntToFixed(220), FW_IntToFixed(440));
  329.     FW_CGroupBox* modemSpeed = FW_NEW(FW_CGroupBox, (ev, this, viewRect, 
  330.                                                 FW_CString(" Modem speed used"), timesBold));
  331.  
  332.     viewRect.Set(fixed40, FW_IntToFixed(380), FW_IntToFixed(210), FW_IntToFixed(396));
  333.     FW_CButton* radio1 = FW_NEW(FW_CButton, (ev, this, k14400RadioID, viewRect, 
  334.                                         FW_kRadioButton, FW_CString("14.4 Kbps or lower")));
  335.     viewRect.Offset(FW_kFixed0, fixed20);
  336.     FW_CButton* radio2 = FW_NEW(FW_CButton, (ev, this, k28800RadioID, viewRect, 
  337.                                         FW_kRadioButton, FW_CString("28.8 Kbps to 256 Kbps")));
  338.     viewRect.Offset(FW_kFixed0, fixed20);
  339.     FW_CButton* radio3 = FW_NEW(FW_CButton, (ev, this, kFasterRadioID, viewRect, 
  340.                                         FW_kRadioButton, FW_CString("Faster than 256 Kbps")));
  341.  
  342.     FW_CRadioCluster* radioCluster = FW_NEW(FW_CRadioCluster, (ev));
  343.     radioCluster->AddRadio(ev, radio2);
  344.     radioCluster->AddRadio(ev, radio1);
  345.     radioCluster->AddRadio(ev, radio3);
  346.     
  347.     // ----- Create a list box (helvetica font, multiple selections, answer to double-clicks)
  348.     viewRect.Set(FW_IntToFixed(250), FW_IntToFixed(362), FW_IntToFixed(400), FW_IntToFixed(440));
  349.     FW_CListBox* listbox = FW_NEW(FW_CListBox, (ev, this, viewRect, kPlatformListBoxID, 10, 
  350.                                     true, helvetica, FW_kListBoxDoubleClickedMsg, false));
  351.     listbox->SetDrawingMode(ev, FALSE);
  352.     listbox->SetStringItem(ev, 1, FW_CString("Mac OS"));
  353.     listbox->SetStringItem(ev, 2, FW_CString("OS/2 Warp"));
  354.     listbox->SetStringItem(ev, 3, FW_CString("Windows 95"));
  355.     listbox->SetStringItem(ev, 4, FW_CString("Windows NT"));
  356.     listbox->SetStringItem(ev, 5, FW_CString("IBM AIX"));
  357.     listbox->SetStringItem(ev, 6, FW_CString("Sun Sparc Solaris"));
  358.     listbox->SetStringItem(ev, 7, FW_CString("Sun OS 4.1.x"));
  359.     listbox->SetStringItem(ev, 8, FW_CString("HP /UX"));
  360.     listbox->SetStringItem(ev, 9, FW_CString("Unix IRIX"));
  361.     listbox->SetStringItem(ev, 10, FW_CString("Unix Linux"));
  362.     listbox->SetDrawingMode(ev, TRUE);
  363.     
  364.     // ----- Create the Add/Remove buttons
  365.     viewRect.Set(FW_IntToFixed(410), FW_IntToFixed(370), FW_IntToFixed(480), FW_IntToFixed(390));
  366.     FW_CButton* addButton = FW_NEW(FW_CButton, (ev, this, kAddButtonID, viewRect, 
  367.                                         FW_kPushButton, FW_CString("Add")));
  368.     viewRect.Set(FW_IntToFixed(410), FW_IntToFixed(400), FW_IntToFixed(480), FW_IntToFixed(420));
  369.     FW_CButton* removeButton = FW_NEW(FW_CButton, (ev, this, kRemoveButtonID, viewRect, 
  370.                                         FW_kPushButton, FW_CString("Remove")));
  371.     removeButton->Disable(ev);
  372.     
  373.     // ----- Create the "browsing time" popup
  374.     viewRect.Set(FW_IntToFixed(30), FW_IntToFixed(477), FW_IntToFixed(230), FW_IntToFixed(497));
  375.     FW_CPopupMenu* popup1 = FW_NEW(FW_CPopupMenu, (ev, this, kBrowseTimePopupID, viewRect, 
  376.                                         kBrowseTimeMenuResID, FW_CString()));
  377.  
  378.     // ----- Create the "online time" popup
  379.     viewRect.Set(FW_IntToFixed(30), FW_IntToFixed(540), FW_IntToFixed(230), FW_IntToFixed(560));
  380.     FW_CPopupMenu* popup2 = FW_NEW(FW_CPopupMenu, (ev, this, kOnlineTimePopupID, viewRect, 
  381.                                         kOnlineTimeMenuResID, FW_CString()));
  382.  
  383.     // ----- Create the "First Discover" radio butttons & their radio cluster
  384.     viewRect.Set(FW_IntToFixed(30), FW_IntToFixed(580), FW_IntToFixed(350), FW_IntToFixed(700));
  385.     FW_CGroupBox* discoverGroupB = FW_NEW(FW_CGroupBox, (ev, this, viewRect, 
  386.                                         FW_CString(" How did you discover ODFWired?"), timesBold));
  387.  
  388.     viewRect.Set(fixed40, FW_IntToFixed(600), FW_IntToFixed(300), FW_IntToFixed(616));
  389.     FW_CButton* radio4 = FW_NEW(FW_CButton, (ev, this, kWorldMouthRadioID, viewRect, 
  390.                                         FW_kRadioButton, FW_CString("Word of mouth")));
  391.     viewRect.Offset(FW_kFixed0, fixed20);
  392.     FW_CButton* radio5 = FW_NEW(FW_CButton, (ev, this, kHyperLinkRadioID, viewRect, 
  393.                                         FW_kRadioButton, FW_CString("Hyperlink from another site:")));
  394.     viewRect.Offset(FW_kFixed0, fixed20);
  395.     FW_CButton* radio6 = FW_NEW(FW_CButton, (ev, this, kMacTechRadioID, viewRect, 
  396.                                         FW_kRadioButton, FW_CString("Ad in MacTech Magazine")));
  397.     viewRect.Offset(FW_kFixed0, fixed20);
  398.     FW_CButton* radio7 = FW_NEW(FW_CButton, (ev, this, kMagazineRadioID, viewRect, 
  399.                                         FW_kRadioButton, FW_CString("Other magazine, newspaper, radio")));
  400.     viewRect.Offset(FW_kFixed0, fixed20);
  401.     FW_CButton* radio8 = FW_NEW(FW_CButton, (ev, this, kOtherRadioID, viewRect, 
  402.                                         FW_kRadioButton, FW_CString("Other")));
  403.     radioCluster = FW_NEW(FW_CRadioCluster, (ev));
  404.     radioCluster->AddRadio(ev, radio4);
  405.     radioCluster->AddRadio(ev, radio5);
  406.     radioCluster->AddRadio(ev, radio6);
  407.     radioCluster->AddRadio(ev, radio7);
  408.     radioCluster->AddRadio(ev, radio8);
  409.     
  410.     // ----- Create the "using OpenDoc" radio butttons & their radio cluster
  411.     viewRect.Set(fixed40, FW_IntToFixed(725), FW_IntToFixed(100), FW_IntToFixed(740));
  412.     FW_CButton* radio9 = FW_NEW(FW_CButton, (ev, this, kYesRadioID, viewRect, 
  413.                                         FW_kRadioButton, FW_CString("Yes")));
  414.     viewRect.Offset(FW_kFixed0, fixed20);
  415.     FW_CButton* radio10 = FW_NEW(FW_CButton, (ev, this, kNoRadioID, viewRect, 
  416.                                         FW_kRadioButton, FW_CString("No")));
  417.     radioCluster = FW_NEW(FW_CRadioCluster, (ev));
  418.     radioCluster->AddRadio(ev, radio9);
  419.     radioCluster->AddRadio(ev, radio10);
  420.  
  421.     // ----- Create the "Subscribe" button at the bottom of the content view
  422.     FW_CString label("Join ODFWired!");
  423.     viewRect.Set(FW_IntToFixed(300), FW_IntToFixed(750), FW_IntToFixed(450), FW_IntToFixed(775));
  424.     FW_CButton* pushButton = FW_NEW(FW_CButton, (ev, this, kSubscribeButtonID, viewRect, 
  425.                                         FW_kPushButton, label));
  426.  
  427.     // ----- Link the frame to the controls it wants to respond to
  428.     //        (CFormFrame was defined as an FW_MReceiver and thus can respond to
  429.     //        notitications.  We could also have decided to make CFormView the
  430.     //        receiver, it's a matter of choice)
  431.     CFormFrame* frame = (CFormFrame*)GetFrame(ev);
  432.     
  433.     pushButton->LinkControlTo(ev, frame);
  434.     addButton->LinkControlTo(ev, frame);
  435.     removeButton->LinkControlTo(ev, frame);
  436.     radio10->LinkControlTo(ev, frame);
  437.     popup1->LinkControlTo(ev, frame);
  438.     
  439.     frame->AddNotifier(listbox, FW_kListBoxDoubleClickedMsg);
  440.  
  441.     // ----- Add a behavior to the list-box to handle mouse clicks
  442.     //        (easier than subclassing FW_CListBox and defining a new resource type)    
  443.     CMouseUpBehavior* behavior = FW_NEW(CMouseUpBehavior, (ev, listbox));
  444.     listbox->AdoptEventHandler(ev, behavior);
  445. #endif
  446. }
  447.  
  448. //----------------------------------------------------------------------------------------
  449. // CFormView::Draw
  450. //----------------------------------------------------------------------------------------
  451.  
  452. void CFormView::Draw(Environment *ev, ODFacet* odFacet, ODShape* invalidShape)
  453. {
  454.     if (fFirstFormOn)
  455.         inherited::Draw(ev, odFacet, invalidShape);
  456.     else 
  457.     {
  458.         // Draw the 2nd picture and the data entered by the user
  459.         inherited::DrawAnotherPicture(ev, odFacet, invalidShape, fPicture2);
  460.  
  461.         FW_CViewContext    vc(ev, this, odFacet, invalidShape);
  462.         DrawUserData(ev, vc);
  463.     }
  464.     
  465.     // SubViews of CFormView are drawn recursively after this point.
  466.     
  467.     // Mac Note: If you want to draw Controls with a non-white background color to match
  468.     // the color of their parent view, you need either to define a color table for
  469.     // the window (see CPwdDialogFrame::FacetAdded for an example) or define color tables
  470.     // for individual controls.  See "Inside Macintosh: Macintosh Toolbox Essentials".
  471. }
  472.  
  473. //----------------------------------------------------------------------------------------
  474. // CFormView::CenterInFrame
  475. //----------------------------------------------------------------------------------------
  476.  
  477. void CFormView::CenterInFrame(Environment* ev, FW_CPoint& contentSize, FW_ERedrawVerb redraw)
  478. {
  479.     FW_CPoint    viewSize(GetSize(ev));
  480.     FW_CPoint    viewExtent(GetExtent(ev));
  481.     FW_CPoint    viewLoc;
  482.  
  483.     FW_CRect contentRect(FW_kZeroPoint, contentSize);
  484.     if (GetFrame(ev)->IsRoot(ev) == FALSE)
  485.     {
  486.         contentRect.Inset(FW_kFixedPos1);
  487.         contentSize = contentRect.Size();
  488.     }
  489.         
  490.     // Center the content view if it's smaller, or align it if it's bigger
  491.     if (contentSize.x > viewExtent.x) 
  492.     {
  493.         viewLoc.x = contentRect.left + FW_Half(contentSize.x - viewExtent.x);
  494.         viewSize.x = viewExtent.x;
  495.     }
  496.     else 
  497.     { 
  498.         viewLoc.x = contentRect.left;
  499.         viewSize.x = contentSize.x;
  500.     }
  501.     
  502.     if (contentSize.y > viewExtent.y) 
  503.     {
  504.         viewLoc.y = contentRect.top + FW_Half(contentSize.y - viewExtent.y);
  505.         viewSize.y = viewExtent.y;
  506.     }
  507.     else 
  508.     {
  509.         viewLoc.y = contentRect.top;
  510.         viewSize.y = contentSize.y;
  511.     }
  512.     
  513.     SetLocation(ev, viewLoc, redraw);
  514.     SetSize(ev, viewSize, redraw);
  515. }
  516.  
  517.  
  518. //----------------------------------------------------------------------------------------
  519. // CFormView::AdjustToNewLayout
  520. //----------------------------------------------------------------------------------------
  521.  
  522. void CFormView::AdjustToNewLayout(Environment *ev, const FW_CPoint& oldExtent, 
  523.                                     const FW_CPoint& newExtent, FW_ERedrawVerb redraw)    
  524. {
  525. FW_UNUSED(oldExtent);
  526.  
  527.     // Adjust the new frame size to remove scroll-bar space
  528.     FW_CPoint sbSize = FW_CScrollBar::GetDefaultScrollBarSize();
  529.     FW_CPoint size = newExtent;
  530.     size.x -= sbSize.x;
  531.     size.y -= sbSize.y;
  532.     
  533.     CenterInFrame(ev, size, redraw);
  534.     
  535.     return;
  536. }
  537.  
  538. //----------------------------------------------------------------------------------------
  539. // CFormView::DoMouseDown
  540. //----------------------------------------------------------------------------------------
  541.  
  542. FW_Handled CFormView::DoMouseDown(Environment* ev, const FW_CMouseEvent& theMouseEvent)
  543. {
  544. FW_UNUSED(theMouseEvent);
  545.     // Go back to the first form when clicking on the 2nd one
  546.     if (!fFirstFormOn)
  547.         SwitchForm(ev);
  548.  
  549.     return FW_kHandled;
  550. }
  551.  
  552. //----------------------------------------------------------------------------------------
  553. // CFormView::SwitchForm
  554. //----------------------------------------------------------------------------------------
  555.  
  556. void     CFormView::SwitchForm(Environment* ev)
  557. {
  558.     if (fFirstFormOn)
  559.     {
  560.         fFirstFormOn = FALSE;
  561.         
  562.         // Hide all subviews but don't hide the form view itself
  563.         SetVisible(ev, FALSE, TRUE);
  564.         SetVisible(ev, TRUE, FALSE);
  565.     }
  566.     else
  567.     {
  568.         fFirstFormOn = TRUE;
  569.         
  570.         // Show all subviews
  571.         SetVisible(ev, TRUE, TRUE);
  572.         
  573.     }
  574.     
  575.     // Force a redraw
  576.     Invalidate(ev);
  577. }
  578.  
  579. //----------------------------------------------------------------------------------------
  580. // CFormView::DrawUserData
  581. //----------------------------------------------------------------------------------------
  582.  
  583. void CFormView::DrawUserData(Environment *ev, FW_CViewContext& vc)
  584. {
  585.     FW_CPoint        position;
  586.     FW_Fixed         vDelta = FW_IntToFixed(24);
  587.     int                i;
  588.     
  589.     FW_CString        str;
  590.     FW_CString32    yesStr("Yes");
  591.     FW_CString32    noStr("No");
  592.     
  593.     position.x = FW_IntToFixed(200);
  594.     position.y = FW_IntToFixed(90);
  595.  
  596.     // Edit views
  597.     FW_CEditView*    edview;
  598.     for (i = 0; i < 4; i++)
  599.     {
  600.         edview = (FW_CEditView*)FindViewByID(ev, kFirstNameEdViewID+i);
  601.         str = edview->GetText(ev);
  602.         FW_CTextShape::RenderText(vc, str, position, FW_kNormalFont);
  603.         position.y += vDelta;
  604.     }
  605.     
  606.     // Check box
  607.     FW_CButton*        button;
  608.     button = (FW_CButton*)FindViewByID(ev, kSubscribeCheckID);
  609.     FW_CTextShape::RenderText(vc, button->GetState(ev) ? yesStr : noStr, position, FW_kNormalFont);
  610.     position.y += vDelta;
  611.     
  612.     // Popups
  613.     FW_CPopupMenu* popup1 = (FW_CPopupMenu*) FindViewByID(ev, kBrowseTimePopupID);
  614.     popup1->GetMenuString(ev, str);
  615.     FW_CTextShape::RenderText(vc, str, position, FW_kNormalFont);
  616.     position.y += vDelta;
  617.  
  618.     FW_CPopupMenu* popup2 = (FW_CPopupMenu*) FindViewByID(ev, kOnlineTimePopupID);
  619.     popup2->GetMenuString(ev, str);
  620.     FW_CTextShape::RenderText(vc, str, position, FW_kNormalFont);
  621.     position.y += vDelta;
  622.     
  623.     // Radio buttons (they are all ordered by ids)
  624.     CFormFrame*    frame = (CFormFrame*) GetFrame(ev);
  625.  
  626.     for (i = 0; i < kNumRadioButtons; i++)
  627.     {
  628.         button = (FW_CButton*)FindViewByID(ev, k14400RadioID + i);
  629.         if (button->GetState(ev)) 
  630.         {
  631.             button->GetLabel(ev, str);
  632.             FW_CTextShape::RenderText(vc, str, position, FW_kNormalFont);
  633.             position.y += vDelta;
  634.         }
  635.     }
  636.     
  637.     // List box
  638.     FW_CListBox* list = (FW_CListBox*)FindViewByID(ev, kPlatformListBoxID);
  639.     const short maxPlaforms = 10;
  640.     short platforms[maxPlaforms];
  641.     short numSelected = list->GetSelectedItems(ev, maxPlaforms, platforms);
  642.     if (numSelected > 0)
  643.     {
  644.         for (i = 0; i < numSelected; i++)
  645.         {
  646.             list->GetStringItem(ev, platforms[i], str);
  647.             FW_CTextShape::RenderText(vc, str, position, FW_kNormalFont);            
  648.             position.y += FW_IntToFixed(16);
  649.         }
  650.     }
  651.     
  652. }
  653.  
  654. //----------------------------------------------------------------------------------------
  655. // CFormView::ResetData
  656. //----------------------------------------------------------------------------------------
  657.  
  658. void CFormView::ResetData(Environment *ev)
  659. {
  660.     // Erase the text of the 5 edit views
  661.     FW_CEditView*    edview;
  662.     for (int i = 0; i < 4; i++)
  663.     {
  664.         edview = (FW_CEditView*)FindViewByID(ev, kFirstNameEdViewID+i);
  665.         edview->SetText(ev, FW_CString());
  666.     }
  667.     
  668.     CScrollEdit* scrolledit = (CScrollEdit*)FindViewByID(ev, kFirstNameEdViewID+4);
  669.     scrolledit->SetText(ev, FW_CString());
  670. }
  671.  
  672. //========================================================================================
  673. //    Archiving API with ODFRC resources
  674. //========================================================================================
  675. #if FW_ODFRC_VIEWS
  676.  
  677. //----------------------------------------------------------------------------------------
  678. //    CFormView::Create
  679. //----------------------------------------------------------------------------------------
  680.  
  681. void* CFormView::Create(FW_CReadableStream& stream, FW_ClassTypeConstant type)
  682. {
  683. FW_UNUSED(stream);
  684. FW_UNUSED(type);
  685.     FW_SOMEnvironment ev;
  686.     return FW_NEW(CFormView, (ev));
  687. }
  688.  
  689. //----------------------------------------------------------------------------------------
  690. //    CFormView::Destroy
  691. //----------------------------------------------------------------------------------------
  692.  
  693. void CFormView::Destroy(void* object, FW_ClassTypeConstant type)
  694. {
  695. FW_UNUSED(type);
  696.     CFormView* self = (CFormView*) object;
  697.     delete self;
  698. }
  699.  
  700. //----------------------------------------------------------------------------------------
  701. //    CFormView::Flatten
  702. //----------------------------------------------------------------------------------------
  703.  
  704. void CFormView::Flatten(Environment* ev, FW_CWritableStream& archive) const
  705. {
  706.     FW_CPictSView::Flatten(ev, archive);
  707.     
  708.     // [LSD] to complete
  709. }
  710.  
  711. //----------------------------------------------------------------------------------------
  712. //    CFormView::InitializeFromStream
  713. //----------------------------------------------------------------------------------------
  714. // This method is required to handle the custom resource fields added to the base type
  715.  
  716. void CFormView::InitializeFromStream(Environment* ev, FW_CReadableStream& stream)
  717. {
  718.     // Read-in the base resource first
  719.     FW_CPictSView::InitializeFromStream(ev, stream);
  720.     
  721.     // Initialize the 2nd picture
  722.     FW_ResourceID pictID2;
  723.     stream >> pictID2;
  724.     
  725.     InitializePict(ev, pictID2);
  726.     
  727.     // Read-in the 3 radio-clusters defined in our RFormView type in "Views.fr"
  728.     // (not need to keep them around).
  729.     FW_CRadioCluster* radioCluster;
  730.     
  731.     for (int i = 0; i < kNumRadioClusters; i++) 
  732.     {
  733.         FW_READ_DYNAMIC_OBJECT(stream, &radioCluster, FW_CRadioCluster);
  734.     }    
  735. }
  736.  
  737. #endif // FW_ODFRC_VIEWS
  738.  
  739. //========================================================================================
  740. //    API for reading PPob view resources
  741. //========================================================================================
  742. #if FW_PPOB_VIEWS
  743.  
  744. //----------------------------------------------------------------------------------------
  745. //    FW_CPPobFormView::FW_CPPobFormView
  746. //----------------------------------------------------------------------------------------
  747.  
  748. CPPobFormView::CPPobFormView(Environment*ev, FW_CReadableStream& stream, long type) :
  749.     FW_CPPobPictSView(ev, stream, type)
  750. {
  751.     // CFormView uses a custom PPob view "Form" defined in ODFForm.ppob.  It derives
  752.     // from LPicture and add an extra field to hold the id of the 2nd PICT resource
  753.  
  754.     stream >> fPictID2;
  755. }
  756.  
  757. //----------------------------------------------------------------------------------------
  758. //    FW_CPPobFormView::Create
  759. //----------------------------------------------------------------------------------------
  760.  
  761. void*    CPPobFormView::Create(Environment*ev, FW_CReadableStream& stream, long type)
  762. {
  763.     return (new CPPobFormView(ev, stream, type));
  764. }
  765.  
  766. //----------------------------------------------------------------------------------------
  767. //    CPPobFormView::CreateODFView
  768. //----------------------------------------------------------------------------------------
  769.  
  770. void    CPPobFormView::CreateODFView(Environment* ev)
  771. {
  772.     // Create CFormView instance
  773.     CFormView* view = FW_NEW(CFormView, (ev, fSuperView, fBounds, fPictID, fPictID2));
  774.     view->SetBindings(ev, fBindings);
  775.     
  776.     // Important: all superview classes must call PostCreateODFView before returning
  777.     PostCreateODFView(ev, view);
  778.  
  779.     delete this;    // we don't need you anymore...
  780. }
  781.  
  782. #endif // FW_PPOB_VIEWS
  783.  
  784. //========================================================================================
  785. //    API for reading MacApp view resources
  786. //========================================================================================
  787. #if FW_MACAPP_VIEWS
  788.  
  789. //----------------------------------------------------------------------------------------
  790. //    CMAFormView::CMAFormView
  791. //----------------------------------------------------------------------------------------
  792.  
  793. CMAFormView::CMAFormView(ResType type) :
  794.     FW_CMAPictSView(type)
  795. {
  796. }
  797.  
  798. //----------------------------------------------------------------------------------------
  799. //    CMAFormView::ReadFields
  800. //----------------------------------------------------------------------------------------
  801.  
  802. void CMAFormView::ReadFields(Environment* ev, FW_CReadableStream& stream) 
  803. {
  804.     inherited::ReadFields(ev, stream);
  805.  
  806.     // Read TForm fields
  807.  
  808.     stream >> fPictID2;
  809. }
  810.  
  811. //----------------------------------------------------------------------------------------
  812. //    CMAFormView::Create
  813. //----------------------------------------------------------------------------------------
  814.  
  815. FW_CMAObject*    CMAFormView::Create(ResType type)
  816. {
  817.     return new CMAFormView(type);
  818. }
  819.  
  820. //----------------------------------------------------------------------------------------
  821. //    CMAFormView::CreateODFView
  822. //----------------------------------------------------------------------------------------
  823.  
  824. FW_CView*    CMAFormView::CreateODFView(Environment* ev, FW_CSuperView* superview, FW_MReceiver* receiver)
  825. {
  826.     // Create CFormView instance
  827.     CFormView* view = FW_NEW(CFormView, (ev, superview, fBounds, fPictID, fPictID2));
  828. //    view->SetBindings(ev, fBindings);
  829.  
  830.     return view;
  831. }
  832.  
  833. #endif // FW_MACAPP_VIEWS
  834.  
  835. //========================================================================================
  836. //    class CMouseUpBehavior
  837. //========================================================================================
  838. // Event handler class used to customize the mouse-click action in our list-box.
  839. // Having a behavior allows us to not have to subclass FW_CListBox (and also not to have
  840. // to define a new resource type in the .fr file)
  841.  
  842. FW_DEFINE_AUTO(CMouseUpBehavior)
  843.  
  844. //----------------------------------------------------------------------------------------
  845. //    CMouseUpBehavior::CMouseUpBehavior
  846. //----------------------------------------------------------------------------------------
  847.  
  848. CMouseUpBehavior::CMouseUpBehavior(Environment* ev, FW_CListBox* listBox) :
  849.     FW_MEventHandler(ev, NULL, FW_kNoPriority),
  850.     fListBox(listBox)
  851. {
  852.     FW_END_CONSTRUCTOR
  853. }
  854.  
  855. //----------------------------------------------------------------------------------------
  856. //    CMouseUpBehavior::~CMouseUpBehavior
  857. //----------------------------------------------------------------------------------------
  858.  
  859. CMouseUpBehavior::~CMouseUpBehavior() 
  860. {
  861.     FW_START_DESTRUCTOR
  862. }
  863.  
  864. //----------------------------------------------------------------------------------------
  865. //    CMouseUpBehavior::DoMouseUp
  866. //----------------------------------------------------------------------------------------
  867. // We use the mouse up event to check if the listbox has 1 or more selected items
  868. // and enable the "Delete" button in that case.
  869. // (In that case we cannot use a mouse down event behavior because it would be executed
  870. //  before the listbox's mouse down handler, see FW_MEventHandler::DispatchMouseDown)
  871.  
  872. FW_Handled CMouseUpBehavior::DoMouseUp(Environment* ev, const FW_CMouseEvent& theMouseEvent) 
  873. {
  874. FW_UNUSED(theMouseEvent);
  875.     // Enable the "Delete" button if there are 1 or more selected items
  876.     if (fListBox->GetSelectedItem(ev) > 0)
  877.     {
  878.         FW_CSuperView* formView = fListBox->GetSuperView(ev);
  879.         FW_CButton* rmButton = (FW_CButton*)formView->FindViewByID(ev, kRemoveButtonID);
  880.         FW_ASSERT(rmButton);
  881.         rmButton->Enable(ev);
  882.     }
  883.  
  884.     // let the list-box handle its mouse up event (although it doesn't matter here)
  885.     return FW_kNotHandled;
  886. }
  887.